/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package tnviet.proj.jna.table;

import com.jgoodies.forms.builder.ButtonBarBuilder;
import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.factories.ButtonBarFactory;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.RowFilter;
import javax.swing.RowSorter;
import javax.swing.UIManager;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import javax.swing.text.JTextComponent;
import org.jvnet.substance.api.renderers.SubstanceDefaultTableCellRenderer;
import tnviet.proj.jna.JNCaptor;
import tnviet.proj.jna.JNMainFrame;
import tnviet.proj.jna.Program;
import tnviet.proj.jna.analyzer.JNPacketAnalyzer;
import tnviet.proj.jna.dialog.ColorRulesDialog;
import tnviet.proj.jna.utilities.ResourceManager;

/**
 *
 * @author Administrator
 */
public class JNTablePane extends JPanel{

    public JTable mainTable;
    public JNTableModel model;
    Vector views = new Vector();
    JNCaptor captor = JNCaptor.getInstance();
    JNMainFrame mainFrame;
    TableRowSorter<JNTableModel> sorter;
    JPopupMenu popup;
    int modelFirstUpdatedRow;
    ResourceManager resourceManager = new ResourceManager(this.getClass(), Program.locale);
    JTextField filterField;
    JLabel filterLabel;
    JPanel filterPanel;


    public JNTablePane(JNMainFrame parent) {
        filterField = new JTextField(30);
        filterLabel = new JLabel(resourceManager.getString("filter") + " " + resourceManager.getString("with") + " " +  resourceManager.getString("column"));
        filterLabel.setIcon(resourceManager.createImageIcon("filter16.png", "Filter Field"));
        filterLabel.setLabelFor(filterField);
        JButton clearButton = new JButton(resourceManager.createImageIcon("Eraser-16-icon.png", "Clear"));
        clearButton.setText(resourceManager.getString("clearFilter"));
        clearButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                filterField.setText("");
                int index = mainTable.getSelectedColumn();
                if(index >=0){
                    newFilter(index);
                    mainFrame.UpdateStatusBar();
                }
            }
        });
        
        PanelBuilder builder = new PanelBuilder(new FormLayout("max(100dlu;pref), 5dlu, pref, 5dlu, pref", "pref"));
        CellConstraints cc = new CellConstraints();
        builder.add(filterLabel, cc.xy(1, 1));
        builder.add(filterField, cc.xy(3, 1));
        builder.add(clearButton, cc.xy(5, 1));
        builder.setDefaultDialogBorder();
        this.mainFrame = parent;
        model = new JNTableModel(captor, views);
        mainTable = new JTable(model);
        mainTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        mainTable.getSelectionModel().addListSelectionListener(parent);
        mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
        sorter = new TableRowSorter<JNTableModel>(model);
        mainTable.setRowSorter(sorter);
        //mainTable.getColumnModel().getColumn(2).setCellRenderer(new ProtocolCellRenderer());
        mainTable.setDefaultRenderer(ProtocolColor.class, new ProtocolCellRenderer());
        mainTable.setDefaultRenderer(Date.class, new DateCellRenderer("dd/MM/yyyy"));
        //mainTable.setColumnSelectionAllowed(true);

        JScrollPane tableViewPort = new JScrollPane(mainTable);
        setLayout(new BorderLayout());
        this.add(tableViewPort,BorderLayout.CENTER);
        filterPanel = builder.getPanel();
        this.add(filterPanel, BorderLayout.PAGE_START);
        this.setMinimumSize(new Dimension(0, 0));
        modelFirstUpdatedRow = 0;
        filterField.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                int index = mainTable.getSelectedColumn();
                if(index>=0){
                    newFilter(index);
                    mainFrame.UpdateStatusBar();
                }
            }
        });
    }

    public void setFilterVisible(boolean flag){
        filterPanel.setVisible(flag);
    }
    public void setFilterLabel(){
        String name = mainTable.getColumnName(mainTable.getSelectedColumn());
        filterLabel.setText("Filter column " + name + " :");
    }

    public void setPopupTableHeader(JPopupMenu popup){
        this.popup = popup;
        this.mainTable.getTableHeader().addMouseListener(new PopupTableHeaderMouseListener());
    }

    public void fireTableChanged(){
        int modelCurrentUpdatedRow = captor.getPackets().size();
        if((modelCurrentUpdatedRow - modelFirstUpdatedRow)>0){
            model.fireTableRowsInserted(modelFirstUpdatedRow, modelCurrentUpdatedRow -1);
        }
        this.repaint();
        modelFirstUpdatedRow = modelCurrentUpdatedRow;
    }
    public void clear(){
        modelFirstUpdatedRow = 0;
        model.fireTableStructureChanged();
        model.fireTableDataChanged();
        this.repaint();
    }

//    @SuppressWarnings("empty-statement")
//    public void setJNTableView(JNPacketAnalyzer analyzer, String name, boolean set){
//        mainTable.clearSelection();
//        if(set){
//            views.addElement(new JNTableView(analyzer, name));
//        } else{
//            for(int i=0; i< views.size(); i++){
//                JNTableView view = (JNTableView)views.elementAt(i);
//                if((analyzer.getClass() == (view.analyzer.getClass())) && view.getValueName().equals(name)){
//                    views.removeElement(view);;
//                }
//            }
//        }
//        model.fireTableStructureChanged();
//        this.repaint();
//    }
    public void setJNTableView(JNPacketAnalyzer analyzer, int valueIndex, boolean set){
        mainTable.clearSelection();
        if(set){
            views.addElement(new JNTableView(analyzer, valueIndex));
        } else {
            for(int i=0; i<views.size(); i++){
                JNTableView view = (JNTableView)views.elementAt(i);
                if((analyzer.getClass() == (view.analyzer.getClass()))&&(view.getIndex()==valueIndex)){
                    views.removeElement(view);
                }
            }
        }
        model.fireTableStructureChanged();
        this.repaint();
    }

    public String[] getJNTableViewStatus(){
        String[] status = new String[views.size()];
        for(int i=0; i<status.length;i++){
            JNTableView view = (JNTableView)views.elementAt(i);
            status[i] = view.getAnalyzer().getProtocolName() + "*" + view.getIndex();
        }
        return status;
    }

    public RowSorter getRowSorter(){
        return mainTable.getRowSorter();
    }

    public int getSelectedRow(){
        return mainTable.getSelectedRow();
    }

    public int convertRowIndexToView(int modelRowIndex) {
        return mainTable.convertRowIndexToView(modelRowIndex);
    }

    public int convertRowIndexToModel(int viewRowIndex) {
        return mainTable.convertRowIndexToModel(viewRowIndex);
    }

    public int columnAtPoint(Point point) {
        return mainTable.columnAtPoint(point);
    }

    public void scrollRectToVisible() {
        mainTable.scrollRectToVisible(mainTable.getCellRect(mainTable.getRowCount() -1, mainTable.getColumnCount(), true));
    }
    public void goToFirstPacket(){
        int modelRowCount = model.getRowCount();
        int index0 = -1;
        for(int i = 0; i < modelRowCount; i++){
            index0 = mainTable.convertRowIndexToView(i);
            if(index0 != -1) break;
        }
        if(index0 == -1) return;
        try {
            mainTable.setRowSelectionInterval(index0, index0);
            mainTable.scrollRectToVisible(mainTable.getCellRect(index0, mainTable.getColumnCount(), true));
        } catch (Exception e) {
        }
        
    }
    public void goToLastPacket(){
        int modelRowCount = model.getRowCount();
        int index0 = -1;
        for(int i = modelRowCount-1; i >=0 ; i--){
            index0 = mainTable.convertRowIndexToView(i);
            if(index0 != -1) break;
        }
        
        if(index0 == -1) return;
        try {
            mainTable.setRowSelectionInterval(index0, index0);
            mainTable.scrollRectToVisible(mainTable.getCellRect(index0, mainTable.getColumnCount(), true));
        } catch (Exception e) {
        }
    }
    public void goToPacket(int go){
        int viewGo = mainTable.convertRowIndexToView(go);
        if(viewGo != -1){
            try {
                mainTable.setRowSelectionInterval(viewGo, viewGo);
                mainTable.scrollRectToVisible(mainTable.getCellRect(go, mainTable.getColumnCount(), true));
            } catch (Exception e) {
            }
        } else {
            JOptionPane.showMessageDialog(mainFrame,
                    resourceManager.getString("rowNotVisible"),
                    resourceManager.getString("warning"),
                    JOptionPane.WARNING_MESSAGE);
        }
    }
    public void setIsApplyColorRules(boolean flag){
        model.setIsApplyColorRules(flag);
    }

    public void goToNextRow(){
        int rowCount = mainTable.getRowCount();
        int nextRow = mainTable.getSelectedRow() + 1;
        if((nextRow > 0)&&(nextRow<rowCount)){
            mainTable.setRowSelectionInterval(nextRow, nextRow);
            mainTable.scrollRectToVisible(mainTable.getCellRect(nextRow, mainTable.getColumnCount(), true));
        }
    }
    public void goToPreviousRow(){
        int rowCount = mainTable.getRowCount();
        int previousRow = mainTable.getSelectedRow() - 1;
        if((previousRow >= 0)&&(previousRow<rowCount)){
            mainTable.setRowSelectionInterval(previousRow, previousRow);
            mainTable.scrollRectToVisible(mainTable.getCellRect(previousRow, mainTable.getColumnCount(), true));
        }
    }
    public int getRowCount(){
        return mainTable.getRowCount();
    }
    void newFilter(int columnIndex){
        RowFilter<JNTableModel, Object> rf = null;
        try {
            rf = RowFilter.regexFilter(filterField.getText(), columnIndex);
        } catch (java.util.regex.PatternSyntaxException e) {
            return;
        }
        sorter.setRowFilter(rf);
    }


    class PopupTableHeaderMouseListener extends MouseAdapter{
        public void mousePressed(MouseEvent e) {
        maybeShowPopup(e);
        }

        public void mouseReleased(MouseEvent e) {
            maybeShowPopup(e);
        }

        private void maybeShowPopup(MouseEvent e) {
            if (e.isPopupTrigger()) {
                if(popup != null){
                    popup.show(e.getComponent(),
                           e.getX(), e.getY());
                }
                
            }
        }

    }

    class ProtocolCellRenderer extends SubstanceDefaultTableCellRenderer {

        //SubstanceDefaultTableCellRenderer defaultRenderer = new SubstanceDefaultTableCellRenderer();
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            Component comp;
            if(value instanceof ProtocolColor){
                String protocolName = ((ProtocolColor)value).getProtocol();
                comp = super.getTableCellRendererComponent(table, protocolName, isSelected, hasFocus, row, column);
                ((JLabel)comp).setOpaque(true);
                ((JLabel)comp).setBackground(((ProtocolColor)value).getColor());
            } else {
                comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            }
            return comp;
        }

    }

    class DateCellRenderer extends SubstanceDefaultTableCellRenderer {
        private DateFormat dateFormat;
        public DateCellRenderer(int style){
            super();
            this.setDateFormat(style);
        }
        public DateCellRenderer(String pattern){
            super();
            this.setDateFormat(pattern);
        }

        public void setDateFormat(int style){
            this.dateFormat = DateFormat.getDateInstance(style);
        }
        public void setDateFormat(String pattern){
            this.dateFormat = new SimpleDateFormat(pattern);
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            Component comp =  super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            String val = "";
            if(value instanceof Date){
                val = this.dateFormat.format(value);
            } else val = value.toString();
            if(comp instanceof JTextComponent){
                ((JTextComponent)comp).setText(val);
            } else if(comp instanceof JLabel) {
                ((JLabel)comp).setText(val);
            }
            this.setToolTipText((String) table.getModel().getValueAt(row, 10));
            return comp;
        }
    }
}
